設定工作目錄

setwd("C:\\RData")

載入套件

library(magrittr)
library(ggplot2)
library(magick)

查看支援哪些功能與格式

str(magick_config())
## List of 21
##  $ version           :Class 'numeric_version'  hidden list of 1
##   ..$ : int [1:4] 6 9 9 14
##  $ modules           : logi FALSE
##  $ cairo             : logi TRUE
##  $ fontconfig        : logi FALSE
##  $ freetype          : logi TRUE
##  $ fftw              : logi TRUE
##  $ ghostscript       : logi TRUE
##  $ jpeg              : logi TRUE
##  $ lcms              : logi TRUE
##  $ libopenjp2        : logi FALSE
##  $ lzma              : logi TRUE
##  $ pangocairo        : logi TRUE
##  $ pango             : logi TRUE
##  $ png               : logi TRUE
##  $ rsvg              : logi TRUE
##  $ tiff              : logi TRUE
##  $ webp              : logi TRUE
##  $ wmf               : logi FALSE
##  $ x11               : logi FALSE
##  $ xml               : logi TRUE
##  $ zero-configuration: logi TRUE

讀取圖片 : image_read()

變數類別為magick-image,以下簡稱為image

# image_read(網址或路徑)
BMO <- image_read('https://i.imgur.com/tyzDiJc.png')
class(BMO)
## [1] "magick-image"
BMO

圖片資訊 : image_info()

image_info(BMO)
##   format width height colorspace matte filesize
## 1    PNG   922    798       sRGB FALSE   342435

匯出圖片 : image_write()

image_write(BMO, path = "finn.jpg", format = "png")
image_write(BMO, path = "BMO.jpg", format = "png")

格式轉換 : image_convert()

image_types()
##  [1] "Undefined"            "Bilevel"              "ColorSeparation"     
##  [4] "ColorSeparationAlpha" "ColorSeparationMatte" "Grayscale"           
##  [7] "GrayscaleAlpha"       "GrayscaleMatte"       "Optimize"            
## [10] "Palette"              "PaletteBilevelAlpha"  "PaletteBilevelMatte" 
## [13] "PaletteAlpha"         "PaletteMatte"         "TrueColorAlpha"      
## [16] "TrueColorMatte"       "TrueColor"
BMO.jpg <- image_convert(BMO,"JPEG")
image_info(BMO.jpg)
##   format width height colorspace matte filesize
## 1   JPEG   922    798       sRGB FALSE        0

顯示圖片

image_browse() : 用本機預設瀏覽器顯示圖片

# image_browse(BMO.jpg)

image_display() : 需要X11視窗系統才能顯示

# magick::image_display(BMO)

圖片裁切

image_trim() : 背景會隨fuzz值自動裁切適當範圍,值越大裁切越多

image_trim(BMO, fuzz = 10)

image_trim(BMO, fuzz = 20)

image_chop() : 選擇要裁切的畫素大小,裁切原點為左上角,但右下兩邊我裁減不掉

image_chop(BMO,"120X50")

image_crop() : 選擇裁切尺寸以其裁切起點

geometry格式為AxB+X+Y

裁切起點 : 從左算起第X個、從上算起第Y個畫素

裁切尺度 : 寬 = A個畫素,高 = B個畫素

BMO #原圖

image_crop(BMO.jpg, geometry = "700x700+100+50")

調整圖片大小

image_scale() : 調整圖片尺寸,寬(或高)會隨著等比例縮放

#寬變400畫素
image_scale(BMO, "400")

#高變500畫素
image_scale(BMO, "X500")

#寬不超過400,並且高不超過500
image_scale(BMO, "400X500")

#寬等於400,高等於500,圖片會變形
image_scale(BMO, "400X500!")

image_resize() : 功能和跟read_scale差不多,但放大圖片導致模糊時,可以用filter改變模糊效果

simon <- image_read('https://i.imgur.com/Yv0S5K7.png')
simon

image_resize(simon, "900X700")

image_resize(simon, "900X700", filter = "Point")

image_resize(simon, "900X700", filter = "Sinc")

filter_types()
##  [1] "Undefined"     "Bartlett"      "Blackman"      "Bohman"       
##  [5] "Box"           "Catrom"        "Cosine"        "Cubic"        
##  [9] "Gaussian"      "Hamming"       "Hann"          "Hanning"      
## [13] "Hermite"       "Jinc"          "Kaiser"        "Lagrange"     
## [17] "Lanczos"       "Lanczos2"      "Lanczos2Sharp" "LanczosRadius"
## [21] "LanczosSharp"  "Mitchell"      "Parzen"        "Point"        
## [25] "Quadratic"     "Robidoux"      "RobidouxSharp" "Sinc"         
## [29] "SincFast"      "Spline"        "Triangle"      "Welch"        
## [33] "Welsh"         "Bessel"

顏色填滿效果 : image_fill()

缺點是無法查詢像素點座標,想把牙齒變金色,找得很辛苦

#填充位置point = "+X+Y",fuzz設定模糊範圍
image_fill(BMO, color = "gold", point =  "+390+400", fuzz = 60)

加入邊框 : image_border()

image_border(BMO, "gold", "10x20")  #寬X高

加入背景 : image_background()

無法覆蓋既有背景

image_background(BMO,"gold")

snail <- image_read("https://ugc.kn3.net/i/origin/http://images.wikia.com/adventuretimewithfinnandjake/images/0/07/Waving_Snail.png")
snail

image_background(snail, "gold")

圖片旋轉

image_rotate() : 順時針旋轉若干角度

image_rotate(snail, 30)

image_flip() : 上下翻轉

image_flip(snail)

image_flop() : 左右翻轉

image_flop(snail) 

Guess what?

BMO %>% image_flip %>% image_flop %>% image_rotate(180)

調節色彩(亮度、飽和度、色相)

原圖預設值皆為100,可能是百分比

#亮度(brightness),負無限到正無限,小於0皆為黑色
image_modulate(BMO,brightness = 120,saturation = 100,hue = 100)

#飽和度(saturation),0則為灰階,可以負值
image_modulate(BMO,brightness = 100,saturation = 200,hue = 100)

image_modulate(BMO,brightness = 100,saturation = 0,hue = 100)

image_modulate(BMO,brightness = 100,saturation = -100,hue = 100)

#色相(hue),非度數,hen奇怪
image_modulate(BMO,brightness = 100,saturation = 100,hue = 90)

模糊效果 : image_blur()

高斯模糊,radius跟sigma都要設值才有效果

image_blur(BMO,radius = 10,sigma = 3)

噪點效果 : image_noise()

image_noise(BMO)

image_noise(BMO, noisetype = "Multiplicative")

image_noise(BMO, noisetype = "impulse")

noise_types()
## [1] "Undefined"      "Gaussian"       "Impulse"        "Laplacian"     
## [5] "Multiplicative" "Poisson"        "Random"         "Uniform"

其他圖片效果(拓印、油畫、負片、黑洞)

image_charcoal(BMO) 

image_charcoal(BMO,radius = 5) 

image_charcoal(BMO,radius = 5, sigma = 3) 

image_oilpaint(BMO,radius = 5) #radius要設值才有效果

image_negate(BMO)

image_implode(BMO)

影像卷積(Convolution) : image_convolve()

當濾鏡用較不燒腦,可以用scaling跟bias調節效果

image_convolve(BMO,kernel = 'Ridges',scaling = "120%!",bias = "-5%")

kernel_types() #把這當濾鏡效果會比較不頭疼
##  [1] "Undefined"     "Unity"         "Gaussian"      "DoG"          
##  [5] "LoG"           "Blur"          "Comet"         "Binomial"     
##  [9] "Laplacian"     "Sobel"         "FreiChen"      "Roberts"      
## [13] "Prewitt"       "Compass"       "Kirsch"        "Diamond"      
## [17] "Square"        "Rectangle"     "Disk"          "Octagon"      
## [21] "Plus"          "Cross"         "Ring"          "Peaks"        
## [25] "Edges"         "Corners"       "Diagonals"     "ThinDiagonals"
## [29] "LineEnds"      "LineJunctions" "Ridges"        "ConvexHull"   
## [33] "ThinSe"        "Skeleton"      "Chebyshev"     "Manhattan"    
## [37] "Octagonal"     "Euclidean"     "User Defined"

限制色彩數 : image_quantize()

image_quantize(BMO, max = 3)  #最多用3種顏色畫出BMO

image_quantize(BMO, max = 5)  #最多用5種顏色畫出BMO

image_quantize(BMO, max = 3,colorspace = 'gray') #灰階效果

colorspace_types() #色彩空間,預設多為sRGB(標準RGB色彩空間)
##  [1] "Undefined"   "CIELab"      "CMY"         "CMYK"        "Gray"       
##  [6] "HCL"         "HCLp"        "HSB"         "HSI"         "HSL"        
## [11] "HSV"         "HWB"         "Lab"         "LCH"         "LCHab"      
## [16] "LCHuv"       "LMS"         "Log"         "Luv"         "OHTA"       
## [21] "Rec601Luma"  "Rec601YCbCr" "Rec709Luma"  "Rec709YCbCr" "RGB"        
## [26] "scRGB"       "sRGB"        "Transparent" "XYZ"         "xyY"        
## [31] "YCbCr"       "YDbDr"       "YCC"         "YIQ"         "YPbPr"      
## [36] "YUV"

加上註解 : image_annotate()

文字方塊,不支援中文

#fonts: "mono", "Times", "Helvetica", "Trebuchet","Comic Sans".
image_annotate(
    image = BMO, #圖片
    text = c("BMO the little boy !"), #註解內容
    size=50,       #文字大小
    degrees = -5,    #旋轉角度
    gravity = "south",  #設定座標原點,預設在"NorthWest"
    location = "-10+35",  #註解的座標,跟gravity搭配使用
    color = "blue",  #文字顏色
    strokecolor = "black", #文字邊緣顏色
    boxcolor = "lightgreen", #文字方塊背景顏色
    font = "mono") #字型

gravity_types()
##  [1] "Undefined" "None"      "Center"    "East"      "Forget"   
##  [6] "NorthEast" "North"     "NorthWest" "SouthEast" "South"    
## [11] "SouthWest" "West"      "Static"

搭配piping處理,並做簡單複習

(BMO.light <- BMO %>% 
    image_crop("700x700+100+50") %>% 
    image_border("skyblue","10X10") %>% 
    image_fill("gold","+300+360",fuzz = 60) %>%
    image_fill("gold","+270+355",fuzz = 50) %>%
    image_scale("720") %>% 
    image_annotate(text = c("BMO the golden teeth"),
                   size = 50,
                   gravity = "south", 
                   location = "+0+50",
                   degrees = -5,
                   color = "gold") %>% 
    image_oilpaint(3.5))

(BMO.dark <- BMO %>% 
        image_crop("700x700+100+50") %>% 
        image_border("skyblue","10X10") %>% 
        image_fill("gold","+300+360",fuzz = 60) %>%
        image_fill("gold","+270+355",fuzz = 50) %>%
        image_scale("720") %>% 
        image_flop %>%
        image_annotate(text = c("BMO the blue teeth"),
                       gravity = "south",
                       size = 50,
                       location = "+0+50",
                       degrees = 5,
                       color = "gold") %>%
        image_modulate(b = 110, s = -100) %>% 
        image_oilpaint(3.5))

合併圖片: image_append()

水平合併

image_append(c(BMO.dark,BMO.light)) 

鉛直合併

stack <- image_append(c(BMO.dark,BMO.light),stack = T) 
stack

影像合成

image_mosaic():將數張圖依次加疊成一張靜圖,每張圖畫素不受影響

pic1 <- image_read('https://orig00.deviantart.net/cf11/f/2012/220/4/6/adventure_time_tree_house_by_transparentstuff-d5adrao.png') %>% image_scale("720")
pic2 <- image_read("http://3rd-strike.com/wp-content/uploads/2015/02/Adventure-Time.png")

image_mosaic(c(pic1, pic2)) 

image_mosaic(c(pic2, pic1))

image_flatten() :同樣依次疊加,但尺寸以第一張圖的畫素為準

pic2%>% image_border("black","10X10")

image_flatten(c(pic2, pic1))

pic1 %>% image_border("black","10X10")

image_flatten(c(pic1, pic2))

#operator可以選擇影像的疊加方式,見下方示意圖
layer <- c(pic1, pic2)
image_flatten(layer, operator = 'MinusSrc')

image_flatten(layer, operator = 'HardLight')

operator示意圖,有些圖看起來好像沒差

compose_types() :

依次疊加,畫素以第一張為主,offset可以調整圖片位置

pic3 <- image_read("https://i.imgur.com/w19H9ZC.png") %>% image_scale("360X300")
pic3

image_composite(image = pic1, #被疊加的影像
                composite_image = pic3, #欲疊加的影像
                operator = "over",
                offset = "+100+200") #調整圖片位置

影像合成範例

想先將pic3旋轉、縮小,注意要先設定背景為none,否則旋轉後增加的面積會自動留白,比較下方例子

pic3  %>%
    #image_background("none") %>% 
    image_rotate(-10)  %>% 
    image_scale("350") %>% 
    image_background("skyblue")

pic3  %>%
        image_background("none") %>% 
        image_rotate(-10)  %>% 
        image_scale("350")%>% 
        image_background("skyblue")

pic3.rot <- pic3  %>%
        image_background("none") %>% 
        image_rotate(-10)  %>% 
        image_scale("350")

pic3.rot

#把三張圖疊圖,並適當調整位置、大小,裁切並輸出
AT <- pic1 %>% 
    #將pic3疊到pic1,並適當調整位置
    image_composite(pic3.rot,
                    operator = "over",
                    offset = "+80+180") %>% 
    #再繼續將pic2疊上,調整位置
    image_composite(image_scale(pic2,"500"),
                    operator = "over",
                    offset = "+0+20") %>% 
    #圖片右方多餘,裁切影片
    image_crop("500X500") %>% 
    #加上註解
    image_annotate(text = "Finn & Jack", 
                   gravity = "southeast",
                   location = "+15+10",
                   size = 20,color = "black",
                   font = "Comic Sans") %>%
    #原無背景,加入背景顏色,在R跑沒問題,MD就失效了
    image_background("skyblue") %>% 
    image_scale("720X720")
AT

局部馬賽克效果

part_mosaic <- function(image.magick, geometry){
    #format.info <- image_info(image.magick)$format
    image.magick %>% 
    #image_convert(format = "PNG") %>% 
    image_crop(geometry = geometry) %>% 
    image_scale(image = ., geometry = 
                paste(0.1*(image_info(.)$width),"X",
                      0.1*(image_info(.)$height))) %>% 
    image_resize(image = ., geometry = 
                    paste(10*(image_info(.)$width),"X",
                          10*(image_info(.)$height)),
                 filter = "box") %>% 
    image_composite(image = image.magick, 
                    composite_image = .,
                    operator = "over",
                    offset = geometry) %>% 
    #image_convert(format = format.info) %>% 
    return()
}

#BMO臉上打馬賽克
part_mosaic(BMO,"370X300+250+170")

svg圖檔也適用,跟我想像的不太一樣

kiwi <- image_read('http://www.webhek.com/wordpress/wp-content/uploads/2014/05/kiwi.svg')

part_mosaic(kiwi,"200X200+350+100")

讀取GIF

跟讀取圖片一樣用image_read()

kat <- image_read("https://tctechcrunch2011.files.wordpress.com/2015/08/safe_image.gif")
kat

length(kat) #GIF的圖片張數
## [1] 140
kat %>% image_scale("500X500") #調整GIF的畫素容易破圖

#動畫處理很久,畢竟140張圖都要處理
kat %>% image_flop %>%
image_annotate("Run Forrest Run", size = 40, color = "blue", gravity = "North")